package user;

import java.awt.geom.Rectangle2D;
import java.util.ArrayList;

import math.Vector2D;

/**
 * @author Ryan Hill
 */
public class User 
{
	/**
	 * Boolean data for different keys
	 */
	private ArrayList<Integer> keycode;
	private ArrayList<Integer> ignoredKeys;
	
	/**
	 * Mouse position and button, null when not being held down
	 */
	private Vector2D mouse;
	private int button;
	
	private Vector2D mouseMove;
	private Vector2D dragAnchor;
	/**
	 * Constructor
	 */
	public User()
	{
		keycode = new ArrayList<Integer>();
		ignoredKeys = new ArrayList<Integer>();
		button = -1;
		mouseMove = new Vector2D();
		new Vector2D();
	}
		
	/**
	 * @return mouse location, null if not held down
	 */
	public Vector2D getMousePos()
	{
		return mouse;
	}
	
	public void doneWithMouse()
	{
		mouseRelease();
	}
	
	public Vector2D getMouseMove()
	{
		return mouseMove;
	}
	
	/**
	 * 
	 * @return a rectangle that represents the area selected by a drag
	 */
	public Rectangle2D.Double getDragArea()
	{
		return (mouse == null) ? null : new Rectangle2D.Double(dragAnchor.getX(), dragAnchor.getY(), mouse.getX() - dragAnchor.getX(), mouse.getY() - dragAnchor.getY());
	}
	
	/**
	 * @return button on mouse being held down, -1 if not held down
	 */
	public int getButton()
	{
		return button;
	}
	
	/**
	 * Click the mouse and notify the user
	 * 
	 * @param b button clicked
	 * @param v location of mouse
	 */
	public void mouseClick( int b, Vector2D v )
	{
		button = b;
		mouse = v;
		//Set a drag anchor if it hasn't already
		if(dragAnchor == null)
			dragAnchor = v;
	}
	
	/**
	 * Release all mouse data
	 */
	public void mouseRelease()
	{
		button = -1;
		mouse = null;
		dragAnchor = null;
	}
	
	public void mouseMove( Vector2D v )
	{
		mouseMove = v;
	}
	
	/**
	 * Press a key down and notify the user
	 * 
	 * @param key the key code for the key being pressed
	 */
	public void keyPressed( int key )
	{
		if(!keyIsPressed(key))
			keycode.add(key);
	}
	
	/**
	 * Release a key and notify the user
	 * 
	 * @param key the key code for the key being released
	 */
	public void releaseKey(int key)
	{
		//find the key in keycode and remove it
		for(int i=0;i<keycode.size();i++)
		{
			if(keycode.get(i) == key)
				keycode.remove(i);
		}
		
		//remove it from the ignored keys list if necessary
		for(int i=0;i<ignoredKeys.size();i++)
		{
			if(ignoredKeys.get(i) == key)
			{
				ignoredKeys.remove(i);
				break;
			}
		}
	}
	
	/**
	 * Forcing is when key may not be released yet, but we don't want to listen to it
	 * @param key
	 */
	public void forceReleaseKey(int key)
	{
		//find the key in keycode and remove it
		for(int i=0;i<keycode.size();i++)
		{
			if(keycode.get(i) == key)
			{
				//ignore that key until it is actually released
				ignoredKeys.add(keycode.get(i));
				keycode.remove(i);
				break;
			}
		}
	}
	public ArrayList<Integer> getKeysPressed()
	{
		return keycode;
	}
	
	private boolean keyIsIgnored(int key)
	{
		for(int k : ignoredKeys)
		{
			if(k == key)
				return true;
		}
		return false;
	}
	
	public boolean keyIsPressed(int key)
	{
		if(keyIsIgnored(key))
			return false;
		for(int k : keycode)
		{
			if(k == key)
				return true;
		}
		return false;
	}
	
}

